<?php


namespace app\community\sms;

use Exception;
use iflow\Helper\Str\Str;
use iflow\Utils\basicTools;

class smsUtil
{
    public array $config;

    public ?object $sms = null;

    public array $_user = [];

    // 发送短信 or 发送邮件
    private string $sendType;
    // 发送短信处理类
    private string $sms_service;

    private string $uuid;

    private array $sms_model = [];

    /**
     * SendSmsUtil constructor.
     * @param string $config
     * @param array $client_config
     */
    public function __construct(string $config = "", public array $client_config = []) {
        $this->config = config('sms@'.$config);

        // 发送信息类型 手机、邮箱
        $this->sendType = $this->client_config['sms_service'] === 'send_mail' ? 'email' : 'phone';
        $this->sms_service = $this->config['sms_services'][$this->client_config['sms_service']] ?? '';

        // 发送短信模型事件
        $this->sms_model = $this->config['sms_model'][$this->client_config['sms_model']] ?? [];

        $this->uuid = Str::genUuid();
        return $this;
    }

    /**
     * 发送验证码
     * @return bool|string
     * @throws Exception
     */
    public function setup(): bool|string
    {
        if (count($this->sms_model) === 0) return "未知短信模型， 请重试";

        if ($this->sms_service_init($this->client_config['sms_service']) === false) return "未知短信运营商";

        if ($this->verification_phone_exists($this->client_config['sms_model'])) {
            if ($this->verification_user_info($this->client_config['sms_model'])) {
                if (!$this->save_user_change_model()) return "创建用户验证模型失败请重试";
                return $this->send_sms() ? true : "短信发送失败， 请重试";
            }
            return "用户尚未登录, 请登录和重试";
        } else {
            return "验证手机号码信息失败， 请重试";
        }
    }

    /**
     * 验证用户是否需要登录
     * @param string $sms_model
     * @return mixed
     * @throws \Exception
     */
    public function verification_user_info(string $sms_model): mixed
    {
        if (in_array($sms_model, $this->config['is_login'])) {
            return $this->_user = session('userInfo') ?: [];
        }
        return true;
    }

    /**
     * 验证手机号码是否存在
     * @param string $sms_model
     * @return bool
     * @throws \Exception
     */
    public function verification_phone_exists(string $sms_model): bool
    {
        if (isset($this->config['is_phone_exists'][$sms_model])) {
            // 验证是否存在该方法
            if (class_exists($this->config['get_user_model'])) {
                $get_user_model = new $this->config['get_user_model'];
                $get_user_func = $this->config['get_user_func'];
                // 验证该类是否有该方法
                if (method_exists($get_user_model, $this->config['get_user_func'])) {
                    // 验证手机/邮箱是否存在
                    $this->_user = call_user_func([$get_user_model, $get_user_func], [
                        $this->sendType => $this -> client_config['phone']
                    ]);
                    if (count($this->_user) > 0) {
                        if ($this->_user['uid']  == session('userInfo')['uid']) return true;
                        return $this->config['is_phone_exists'][$sms_model];
                    }
                }
            }
            throw new Exception("获取用户信息类不存在");
        }
        return true;
    }

    /**
     * 保存用户操作
     * @return $this
     */
    public function save_user_change_model(): static
    {

        $code = $this->client_config['code'] ?? Str::RandomStr(6);

        $send_data = $this->client_config['send_data'] ?? '';

        if ($this->sms_model['content_type'] === 'code') {
            if ($this->sendType === 'email' && $send_data === '') {
                $send_data = sprintf($this->sms_model['content'], $code);
            } else {
                $send_data = $code;
            }
        }

        $this->client_config['send_data'] = $send_data;
        if (is_string($this->config['save_model'])) {
            if (! class_exists($this->config['save_model'])) return $this;
            $save_model = new $this->config['save_model'];
            $save_model -> create([
                'sms_send_data' => $this->client_config['send_data'],
                'uid' => $this->_user['uid'] ?? ($this->client_config['uid'] ?? 0),
                'uuid' => $this->uuid,
                'email_or_phone' => $this->client_config['phone'] ?? ($this->client_config['email'] ?? '-1'),
                'sms_model' => $this->client_config['sms_model'],
                'sms_send_code' => $code,
                'sms_status' => 2, // 操作状态
                'expire_time' => time() + (3 * 1000)
            ]);
        }
        return $this;
    }

    /**
     * 验证短信运营商配置
     * @param string $sms_service
     * @return mixed
     */
    public function sms_service_init(string $sms_service): bool
    {
        if ($sms_service === 'send_mail') return true;
        return class_exists($this->sms_service);
    }

    /**
     * 发送短信、邮件
     * @return bool
     */
    public function send_sms() : bool
    {

        $fun = $this->client_config['sms_service'];
        // 如果是发送邮件
        if (strtolower($fun) === 'send_mail') {
            return emails(
                is_array($this->client_config['to']) ? $this->client_config['to'] : [$this->client_config['to']],
                $this->client_config['send_data'],
                subject: $this->sms_model['title']
            );
        }

        return app() -> make($this->sms_service) -> $fun(
            $this->client_config['phone'],
            $this->client_config['send_data'],
            $this->config["sms_model_bind_template_code"][$this->client_config['sms_model']]
        );
    }

    /**
     * @return string
     */
    public function getUuid(): string
    {
        return $this->uuid;
    }
}